From 86c60bb2d57197738bea0e016cb82eef026776eb Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Thu, 8 Nov 2007 14:50:01 +0000 Subject: [PATCH] hvm: Clean up buf_ioreq handling. Also, disable stdvga caching on hvm save/restore, as the shadow vga state is not preserved. Signed-off-by: Keir Fraser --- tools/ioemu/target-i386-dm/helper2.c | 17 +++++++++-------- xen/arch/ia64/vmx/mmio.c | 3 ++- xen/arch/ia64/vmx/save.c | 6 ++---- xen/arch/x86/hvm/intercept.c | 18 ++++++++++-------- xen/arch/x86/hvm/save.c | 12 +++++++----- xen/arch/x86/hvm/stdvga.c | 4 +++- xen/common/hvm/save.c | 4 ++-- xen/include/public/hvm/ioreq.h | 11 ++++++----- xen/include/xen/hvm/save.h | 4 ++-- 9 files changed, 43 insertions(+), 36 deletions(-) diff --git a/tools/ioemu/target-i386-dm/helper2.c b/tools/ioemu/target-i386-dm/helper2.c index 56e1dc5ab1..c139f12632 100644 --- a/tools/ioemu/target-i386-dm/helper2.c +++ b/tools/ioemu/target-i386-dm/helper2.c @@ -541,27 +541,28 @@ void __handle_buffered_iopage(CPUState *env) { buf_ioreq_t *buf_req = NULL; ioreq_t req; - int qw = 0; + int qw; if (!buffered_io_page) return; while (buffered_io_page->read_pointer != buffered_io_page->write_pointer) { - memset(&req, 0, sizeof(req)); - buf_req = &buffered_io_page->buf_ioreq[buffered_io_page->read_pointer % - IOREQ_BUFFER_SLOT_NUM]; + buf_req = &buffered_io_page->buf_ioreq[ + buffered_io_page->read_pointer % IOREQ_BUFFER_SLOT_NUM]; req.size = 1UL << buf_req->size; req.count = 1; req.addr = buf_req->addr; req.data = buf_req->data; req.state = STATE_IOREQ_READY; - req.dir = buf_req->dir; + req.dir = buf_req->dir; + req.df = buf_req->df; req.type = buf_req->type; - qw = req.size == 8; + req.data_is_ptr = 0; + qw = (req.size == 8); if (qw) { - buf_req = &buffered_io_page->buf_ioreq[(buffered_io_page->read_pointer+1) % - IOREQ_BUFFER_SLOT_NUM]; + buf_req = &buffered_io_page->buf_ioreq[ + (buffered_io_page->read_pointer+1) % IOREQ_BUFFER_SLOT_NUM]; req.data |= ((uint64_t)buf_req->data) << 32; } diff --git a/xen/arch/ia64/vmx/mmio.c b/xen/arch/ia64/vmx/mmio.c index 2c247b7403..c72969a9b6 100644 --- a/xen/arch/ia64/vmx/mmio.c +++ b/xen/arch/ia64/vmx/mmio.c @@ -65,7 +65,7 @@ static int hvm_buffered_io_intercept(ioreq_t *p) /* ignore READ ioreq_t and anything buffered io can't deal with */ if (p->dir == IOREQ_READ || p->addr > 0xFFFFFUL || - p->data_is_ptr || p->df || p->count != 1) + p->data_is_ptr || p->count != 1) return 0; for (i = 0; i < HVM_BUFFERED_IO_RANGE_NR; i++) { @@ -80,6 +80,7 @@ static int hvm_buffered_io_intercept(ioreq_t *p) bp.type = p->type; bp.dir = p->dir; + bp.df = p->df; switch (p->size) { case 1: bp.size = 0; diff --git a/xen/arch/ia64/vmx/save.c b/xen/arch/ia64/vmx/save.c index 3d4eddd44f..f0e9145f91 100644 --- a/xen/arch/ia64/vmx/save.c +++ b/xen/arch/ia64/vmx/save.c @@ -23,8 +23,7 @@ #include #include -void -arch_hvm_save(struct hvm_save_header *hdr) +void arch_hvm_save(struct domain *d, struct hvm_save_header *hdr) { unsigned int i; @@ -32,8 +31,7 @@ arch_hvm_save(struct hvm_save_header *hdr) hdr->cpuid[i] = ia64_get_cpuid(i); } -int -arch_hvm_load(struct hvm_save_header *hdr) +int arch_hvm_load(struct domain *d, struct hvm_save_header *hdr) { unsigned int i; if (hdr->magic != HVM_FILE_MAGIC) { diff --git a/xen/arch/x86/hvm/intercept.c b/xen/arch/x86/hvm/intercept.c index dc2b1ffbba..be58c05d0c 100644 --- a/xen/arch/x86/hvm/intercept.c +++ b/xen/arch/x86/hvm/intercept.c @@ -163,18 +163,20 @@ int hvm_buffered_io_send(ioreq_t *p) /* Ensure buffered_iopage fits in a page */ BUILD_BUG_ON(sizeof(buffered_iopage_t) > PAGE_SIZE); - /* Return 0 for the cases we can't deal with. */ - if ( (p->addr > 0xffffful) || p->data_is_ptr || p->df || (p->count != 1) ) - { - gdprintk(XENLOG_DEBUG, "slow ioreq. type:%d size:%"PRIu64" addr:0x%" - PRIx64" dir:%d ptr:%d df:%d count:%"PRIu64"\n", - p->type, p->size, p->addr, !!p->dir, - !!p->data_is_ptr, !!p->df, p->count); + /* + * Return 0 for the cases we can't deal with: + * - 'addr' is only a 20-bit field, so we cannot address beyond 1MB + * - we cannot buffer accesses to guest memory buffers, as the guest + * may expect the memory buffer to be synchronously accessed + * - the count field is usually used with data_is_ptr and since we don't + * support data_is_ptr we do not waste space for the count field either + */ + if ( (p->addr > 0xffffful) || p->data_is_ptr || (p->count != 1) ) return 0; - } bp.type = p->type; bp.dir = p->dir; + bp.df = p->df; switch ( p->size ) { case 1: diff --git a/xen/arch/x86/hvm/save.c b/xen/arch/x86/hvm/save.c index 1f75b63682..6d93340c8b 100644 --- a/xen/arch/x86/hvm/save.c +++ b/xen/arch/x86/hvm/save.c @@ -24,8 +24,7 @@ #include #include -void -arch_hvm_save(struct hvm_save_header *hdr) +void arch_hvm_save(struct domain *d, struct hvm_save_header *hdr) { uint32_t eax, ebx, ecx, edx; @@ -36,10 +35,10 @@ arch_hvm_save(struct hvm_save_header *hdr) hdr->pad0 = 0; } -int -arch_hvm_load(struct hvm_save_header *hdr) +int arch_hvm_load(struct domain *d, struct hvm_save_header *hdr) { uint32_t eax, ebx, ecx, edx; + if ( hdr->magic != HVM_FILE_MAGIC ) { gdprintk(XENLOG_ERR, @@ -55,11 +54,14 @@ arch_hvm_load(struct hvm_save_header *hdr) } cpuid(1, &eax, &ebx, &ecx, &edx); - /*TODO: need to define how big a difference is acceptable */ + /* TODO: need to define how big a difference is acceptable? */ if ( hdr->cpuid != eax ) gdprintk(XENLOG_WARNING, "HVM restore: saved CPUID (%#"PRIx32") " "does not match host (%#"PRIx32").\n", hdr->cpuid, eax); + /* VGA state is not saved/restored, so we nobble the cache. */ + d->arch.hvm_domain.stdvga.cache = 0; + return 0; } diff --git a/xen/arch/x86/hvm/stdvga.c b/xen/arch/x86/hvm/stdvga.c index 7d2599ca69..e068c31a0c 100644 --- a/xen/arch/x86/hvm/stdvga.c +++ b/xen/arch/x86/hvm/stdvga.c @@ -220,7 +220,9 @@ static void stdvga_outb(uint64_t addr, uint8_t val) gdprintk(XENLOG_INFO, "entering stdvga and caching modes\n"); } else if ( prev_stdvga && !s->stdvga ) + { gdprintk(XENLOG_INFO, "leaving stdvga\n"); + } } static void stdvga_outv(uint64_t addr, uint64_t data, uint32_t size) @@ -636,7 +638,7 @@ int stdvga_intercept_mmio(ioreq_t *p) buf = mmio_op(s, p); break; default: - gdprintk(XENLOG_ERR, "unsupported mmio request type:%d " + gdprintk(XENLOG_WARNING, "unsupported mmio request type:%d " "addr:0x%04x data:0x%04x size:%d count:%d state:%d " "isptr:%d dir:%d df:%d\n", p->type, (int)p->addr, (int)p->data, (int)p->size, diff --git a/xen/common/hvm/save.c b/xen/common/hvm/save.c index 26ba8ad813..3079363676 100644 --- a/xen/common/hvm/save.c +++ b/xen/common/hvm/save.c @@ -94,7 +94,7 @@ int hvm_save(struct domain *d, hvm_domain_context_t *h) else hdr.changeset = -1ULL; /* Unknown */ - arch_hvm_save(&hdr); + arch_hvm_save(d, &hdr); if ( hvm_save_entry(HEADER, 0, h, &hdr) != 0 ) { @@ -144,7 +144,7 @@ int hvm_load(struct domain *d, hvm_domain_context_t *h) if ( hvm_load_entry(HEADER, h, &hdr) != 0 ) return -1; - if ( arch_hvm_load(&hdr) ) + if ( arch_hvm_load(d, &hdr) ) return -1; c = strrchr(xen_changeset(), ':'); diff --git a/xen/include/public/hvm/ioreq.h b/xen/include/public/hvm/ioreq.h index 18922c4440..456d059d92 100644 --- a/xen/include/public/hvm/ioreq.h +++ b/xen/include/public/hvm/ioreq.h @@ -78,11 +78,12 @@ struct shared_iopage { typedef struct shared_iopage shared_iopage_t; struct buf_ioreq { - uint8_t type; /* I/O type */ - uint8_t dir:1; /* 1=read, 0=write */ - uint8_t size:2; /* 0=>1, 1=>2, 2=>4, 3=>8. If 8, use two buf_ioreqs */ - uint32_t addr:20;/* physical address */ - uint32_t data; /* data */ + uint8_t type; /* I/O type */ + uint8_t df:1; /* EFLAGS.DF */ + uint8_t dir:1; /* 1=read, 0=write */ + uint8_t size:2; /* 0=>1, 1=>2, 2=>4, 3=>8. If 8, use two buf_ioreqs */ + uint32_t addr:20;/* physical address */ + uint32_t data; /* data */ }; typedef struct buf_ioreq buf_ioreq_t; diff --git a/xen/include/xen/hvm/save.h b/xen/include/xen/hvm/save.h index 09298c3334..2842cf0839 100644 --- a/xen/include/xen/hvm/save.h +++ b/xen/include/xen/hvm/save.h @@ -155,7 +155,7 @@ int hvm_load(struct domain *d, hvm_domain_context_t *h); /* Arch-specific definitions. */ struct hvm_save_header; -void arch_hvm_save(struct hvm_save_header *hdr); -int arch_hvm_load(struct hvm_save_header *hdr); +void arch_hvm_save(struct domain *d, struct hvm_save_header *hdr); +int arch_hvm_load(struct domain *d, struct hvm_save_header *hdr); #endif /* __XEN_HVM_SAVE_H__ */ -- 2.30.2